﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using FarseerGames.FarseerPhysics;

using Warlock.Input;
using Warlock.GameStuff.Spells;
using Warlock.GameStuff.Network;

namespace Warlock.GameStuff
{
    class MainGameScreen : IGameScreen
    {
        //===Singleton====================================================
        static PhysicsSimulator _physSim;
        /// <summary>
        /// Der einzige(!) PhysikSimulator
        /// </summary>
        public static PhysicsSimulator PhysicsSimulator
        {
            get
            {
                if (_physSim == null)
                    _physSim = new PhysicsSimulator(new Vector2(0, 0));
                return _physSim;
            }
        }
        //================================================================

        public Game1 MainGame { get; set; }

        public event SpellCreatedEventHandler SpellCreated;

        static SortedList<int, Playerinfo> gamers = new SortedList<int, Playerinfo>();
        static Netcom.Client Client;
        static int Persid;
        //Spiel-Objekte
        List<BaseSpell> spells = new List<BaseSpell>();
        Player mainPlayer;
        SortedList<int, Player> otherplayer = new SortedList<int, Player>();
        GraphicsDevice agraphics;
        List<int> Playerids = new List<int>();
        List<int> ClientPlayerids = new List<int>();


        public MainGameScreen(Game1 mainGame)
        {
            MainGame = mainGame;
        }

        /// <summary>
        /// Setzt Positionen der Gegenstaende Lebenspunkte etc...
        /// Laedt dann aus .map File
        /// </summary>
        void StartGame()
        {
            /*
            //Testweise
            BaseSpell spell = new BaseSpell(new Vector2(30, 30), 50, 100);
            spell.LoadContent(MainGame.Content);
            spells.Add(spell);
             */
        }


        public void Initialize(GraphicsDeviceManager graphics, ContentManager content)
        {
            //Hier Initialisierung von Grafiken Spieleranzahl etc.
            if (Properties.Settings.Default.Gamemode == "Multiplayer")
            {
                Client = new Netcom.Client(Properties.Settings.Default.ConIP, Properties.Settings.Default.ConPort);
                gamers = Netcom.Client.Gamer;
                mainPlayer = new Player("GameThumbnail.png", new Vector2(100, 100), Properties.Settings.Default.PlayerName, 100, Game1.Manager.GraphicsDevice);
                mainPlayer.UpdateMovement(Keys.W, Keys.S, Keys.A, Keys.D);
                mainPlayer.UpdateRotation(new Vector2(Mouse.GetState().X, Mouse.GetState().Y));
                Netcom.Client.sender.Send(Netcom.Client.TCP1, mainPlayer.ToString(), WarlockProt.Packettype.newPlayer);
               
            }
            if (Properties.Settings.Default.Gamemode == "MultiplayerS")
            {
                Client = new Netcom.Client("127.0.0.1", Properties.Settings.Default.ConPort);
                gamers = Netcom.Client.Gamer;
                mainPlayer = new Player("GameThumbnail.png", new Vector2(100, 100), Properties.Settings.Default.PlayerName, 100, Game1.Manager.GraphicsDevice);
                Netcom.Client.sender.Send(Netcom.Client.TCP1, mainPlayer.ToString(), WarlockProt.Packettype.newPlayer);
                
            }
            agraphics = Game1.Manager.GraphicsDevice;            

            StartGame();
        }

        public void UnloadContent()
        {
        }

        bool persidset = false;

        public void Update(GameTime gameTime)
        {
            gamers = new SortedList<int, Playerinfo>(Netcom.Client.Gamer);
            
            //gamers = Netcom.Client.Gamer;
            int[] buffer = new int[Netcom.Client.Playerids.Count];
            Netcom.Client.Playerids.CopyTo(buffer);
            ClientPlayerids = new List<int>(buffer);
            

            if (Netcom.Client.persid != -1 && !persidset)
            {
                Playerids.Add(Netcom.Client.persid);
                mainPlayer.NetworkID = Netcom.Client.persid;
                persidset = true;
            }
            Console.Clear();
            Console.WriteLine("Player ID's: "+ClientPlayerids.Count);
            Console.WriteLine("Listet Player: " + gamers.Count);
            if (Persid != -1)
            {
                foreach (int i in ClientPlayerids)
                {

                    bool isthere = false;
                    if (Playerids.Contains(i))
                    {
                        isthere = true;
                    }
                    if (!isthere)
                    {
                        Player d = new Player(gamers[i].ToString(), agraphics);
                        otherplayer.Add(i, d);
                        Playerids.Add(i);
                    }
                    else
                    {
                        if (i != Netcom.Client.persid)
                        {
                            otherplayer[i].Position = gamers[i].Position;
                            otherplayer[i].Health = gamers[i].Health;
                            otherplayer[i].Rotation = gamers[i].Rotation;
                            //Console.WriteLine(SplitPlayerinfo[3] + " " + SplitPlayerinfo[2]);
                        }
                    }

                }

                Netcom.Client.sender.Send(Netcom.Client.TCP1, mainPlayer.ToString(), WarlockProt.Packettype.PlayerUpdate);
                Netcom.Client.sender.Send(Netcom.Client.TCP1, "0", WarlockProt.Packettype.PlayerlistUpdate);
                mainPlayer.UpdateMovement(Keys.W, Keys.S, Keys.A, Keys.D);
                mainPlayer.UpdateRotation(new Vector2(Mouse.GetState().X, Mouse.GetState().Y));
            }
            //Eventuell mit LINQ saemtliche Listen verbinden, also spells, player, walls, grounds, etc in eine Sprite-Liste packen

            /*
             * Beispiel
             *
            foreach (Sprite s in sprites)
            {
                s.Update(gameTime);
            }
             * 
             * Eigentliche Update-Methode wird in jedem Sprite selber ausgefuehrt
             * */
        }



        static Vector2 StringtoVector(String Vector)
        {
            String one = Vector.Replace("{", "");
            String Tow = one.Replace("}", "");
            String[] cords = new string[2];
            one = Tow.Replace("X", "");
            Tow = one.Replace("Y", "");
            one = Tow.Replace(":", "");
            cords = one.Split(new char[] { ' ' });
            Vector2 returner = new Vector2(Convert.ToSingle(cords[0]), Convert.ToSingle(cords[1]));
            return returner;
        }

        public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
        {
            //Eventuell mit LINQ saemtliche Listen verbinden, also spells, player, walls, grounds, etc in eine Sprite-Liste packen

            /*
             * Beispiel
             *
            foreach (Sprite s in sprites)
            {
                s.Draw(spriteBatch, gameTime);
            }
             * 
             * Eigentliche Draw-Methode wird in jedem Sprite selber ausgefuehrt
             * */
            
            spriteBatch.Begin();
            foreach (BaseSpell spell in spells)
            {
                spell.Draw(spriteBatch, gameTime);
            }
            PlayerManager.Draw(spriteBatch, gameTime);
            
            //mainPlayer.Draw(spriteBatch, gameTime);

            spriteBatch.End();
        }

        /// <summary>
        /// Ueber diese Methode kann von außen, das SpellCreatedEvent aufgerufen werden
        /// </summary>
        /// <param name="spell">Der neue Zauber.</param>
        /// <param name="damage">Der Schaden, den der Spell verursacht.</param>
        /// <param name="owner">Der Spieler, der den Spell gestartet hat.</param>
        public void OnSpellCreated(BaseSpell spell, int damage, Player owner)
        {
            if(SpellCreated != null)
                SpellCreated(spell, new SpellCreatedEventArgs(damage, owner));
        }
    }
}